#include <stdlib.h>
#include "all.hpp"
#include "log.h"
#include "default_interface.hpp"
#include "share_ptr_session.hpp"
#include "main_service.h"
#include "util/config.h"

// share session.
class CMainSession;
using sharePtrSession = anet::tcp::CSharePtrSession<CMainSession>;

class CMainSession {
public:
	CMainSession() : m_session(nullptr), m_close(true) {
	}
	virtual ~CMainSession() {}

public:
	// template function interface.
	static CMainSession* Create() {
		return new CMainSession();
	}
	void OnRelease() {
		m_close = true;
		delete this;
	}

	void SetSession(sharePtrSession* pSession) {
		m_session = pSession;
	}
	void OnMessage(const char* msg, int len) {
		this->Send(msg, len);
	}
	void OnConnected() {
		m_close = false;
		LogAdebug("connected");
	}
	void OnTerminate() {
		LogAdebug("terminate");
	}

	void Send(const char* msg, int len) {
		m_session->Send(msg, len);
	}

private:
	sharePtrSession* m_session;
	bool m_close;
};

int main(int argc, char* argv[]) {
	anet::utils::CConfig reader;
	if (!reader.Parse("./gate.conf")) {
		return -1;
	}

	// address.
	auto ip = reader.GetNode<std::string>("main/ip", "");
	auto port = reader.GetNode<unsigned short>("main/port", 0);

	// level information.
	auto level = reader.GetNode<int>("main/level", 0);
	auto level_path = reader.GetNode<std::string>("main/level_path", "./log");
	auto level_interval = reader.GetNode<int>("main/level_interval", 1000);

	// init log module
	anet::log::initLog(level_path, "gate-net", anet::log::eLogLevel(level), level_interval);

	// tcp server.
	anet::tcp::Server server(3);
	server->setPacketParser(new anet::tcp::CBigCodec());
	// server->setSessionFactory(new anet::tcp::CSessionFactory());
	server->setSessionFactory(new anet::tcp::CSharePtrSessionFactory<CMainSession>);
	char addr[1024];
	std::snprintf(addr, sizeof(addr)-1, "%s:%d", ip.c_str(), port);
	if (!server->start(addr)) {
		return -1;
	}

	for (;;) {
		if (!anet::tcp::CMainService::instance().run(1024)) {
			sleepMS(1);
		}
		// sleepMS(1000);
	}

	return 0;
}
